#include "Ultrasonic.h"

void Delay10us(void)	{
	unsigned char data i;
 
	i = 78;
	while (--i);
}


static u16 time1 = 0;
static u16 time2 = 0;
void Exti1_call() {
    // 下降沿 定时器停止计时，获取数据，并清空计时寄存器。
    if(ULTRA_ECHO == 0) {
        
        AUXR &= ~(1<<4);
        time2 = (T2H << 8) | T2L;
        T2H = T2L = 0;        
        
    }
    // 上升沿， 获取定时器计时，重置计时寄存器，并重新计时
    if(ULTRA_ECHO == 1) {
        AUXR &= ~(1<<4);
        time1 = (T2H << 8) | T2L;
        T2H = T2L = 0;
        
        AUXR = (AUXR & ~0x10) | (1 << 4);
    }
	
}

void Ultrasonic_Exti_config(void) {
    EXTI_InitTypeDef xdata Exti_InitStructure;							//结构定义

    Exti_InitStructure.EXTI_Mode      = EXT_MODE_RiseFall;//中断模式,   EXT_MODE_RiseFall,EXT_MODE_Fall
    Ext_Inilize(EXT_INT1,&Exti_InitStructure);				//初始化
    NVIC_INT1_Init(ENABLE,Priority_0);		//中断使能, ENABLE/DISABLE; 优先级(低到高) Priority_0,Priority_1,Priority_2,Priority_3
}

void Ultrasonic_Timer_config(void) {
	TIM_InitTypeDef	xdata TIM_InitStructure;						//结构定义
	//定时器2做16位自动重装, 中断频率为1000HZ
	TIM_InitStructure.TIM_ClkSource = TIM_CLOCK_12T;		//指定时钟源,     TIM_CLOCK_1T,TIM_CLOCK_12T,TIM_CLOCK_Ext
	TIM_InitStructure.TIM_ClkOut    = DISABLE;				//是否输出高速脉冲, ENABLE或DISABLE
	TIM_InitStructure.TIM_Value     = 0;				    //初值
	TIM_InitStructure.TIM_PS        = 0;					//8位预分频器(n+1), 0~255, (注意:并非所有系列都有此寄存器,详情请查看数据手册)
	TIM_InitStructure.TIM_Run       = ENABLE;				//是否初始化后启动定时器, ENABLE 或 DISABLE
	Timer_Inilize(Timer2,&TIM_InitStructure);				//初始化Timer2	  Timer0,Timer1,Timer2,Timer3,Timer4

}


void Ultrasonic_init(void) {
    EA = 1;
    ULTRASONIC_GPIO();
    Ultrasonic_Exti_config();
    Ultrasonic_Timer_config();
}

u8 Ultrasonic_get_distance(float *distance) {

    // 拉高 10us RTIG， 至少 10us
	ULTRA_TRIG = 1;
	Delay10us();
	ULTRA_TRIG = 0;

   	// 当 TRIG 拉低 定时器开始计时，直到 ECHO 产生上升沿，
    AUXR = (AUXR & ~0x10) | (1 << 4);

    
    // 实际使用超声波的频率肯定没有那么快，手册上说最好间隔60ms
    // 所以 等待5ms 检测 有没有正常发送超声波，超时返回 错误类型并停下计时器
    os_wait2(K_TMO, 1);
    // 将获取的 u16 数据转化为 float ms
    
    if(TimeToMS(time1) >  4) {
        AUXR &= ~(1<<4);
        return -1;
    }
    
    // 测距的 最大距离 是 4M 400cm, 也就是 23.5ms， 和之前的 加起来也不过 不到30ms，
    // 正常使用 超声波的 频率不会这么高， 手册也推荐 间隔60ms
    os_wait2(K_TMO,  5);
    if(TimeToMS(time2) > 25) {
        AUXR &= ~(1<<4);
        return -2;
    }

    
    // 所有步骤 都正常就 计算 距离 返回出去
    *distance = TimeToMS(time2) * 17 + 0.1;
		
    return 0;

}


u8 Ultrasonic_get_floor(u8 *floor, u8 status) {

    int temp = 0;

    // 拉高 10us RTIG， 至少 10us
	ULTRA_TRIG = 1;
	Delay10us();
	ULTRA_TRIG = 0;

   	// 当 TRIG 拉低 定时器开始计时，直到 ECHO 产生上升沿，
    AUXR = (AUXR & ~0x10) | (1 << 4);

    
    // 实际使用超声波的频率肯定没有那么快，手册上说最好间隔60ms
    // 所以 等待5ms 检测 有没有正常发送超声波，超时返回 错误类型并停下计时器
    os_wait2(K_TMO, 1);
    // 将获取的 u16 数据转化为 float ms
    

    if(TimeToMS(time1) >  4) {
        AUXR &= ~(1<<4);
        return -1;
    }
    
    // 测距的 最大距离 是 4M 400cm, 也就是 23.5ms， 和之前的 加起来也不过 不到30ms，
    // 正常使用 超声波的 频率不会这么高， 手册也推荐 间隔60ms
    os_wait2(K_TMO,  5);
    if(TimeToMS(time2) > 25) {
        AUXR &= ~(1<<4);
        return -2;
    }

    
    // 所有步骤 都正常就 计算 距离 返回出去
    temp = (int)((TimeToMS(time2) * 17 + 0.1) / 3);

    if(status == 1) {
        *floor = temp;
        //printf("temp1 :%d\r\n", temp);
    } else if(status == 2) {
        temp += 1;
        if(temp > 3) temp = 3;
        *floor = temp;
        //printf("temp2 :%d\r\n", temp);
    } else {
        if((TimeToMS(time2) * 17 + 0.1) / 3 - temp > 0.75) {
            //printf("temp0 :%d\r\n", temp);
            temp = temp + 1;
            *floor = temp > 3 ? 3 : temp;
        } else if((TimeToMS(time2) * 17 + 0.1) / 3- temp < 0.25) {
            *floor = temp;
            //printf("temp0 :%d\r\n", temp);
        }
    }

    return 0;
}